ARM板移植Linux系统启动(六)烧写系统到emmc

您所在的位置:网站首页 linux板子上电启动程序 开源 ARM板移植Linux系统启动(六)烧写系统到emmc

ARM板移植Linux系统启动(六)烧写系统到emmc

2024-02-20 17:52| 来源: 网络整理| 查看: 265

能够从Uart把系统跑起来,基本上已经完成了移植工作的关键。但此时自动的引导流程还没有建立好,要想让系统能正常启动,必须将数据烧写到存储设备里去。烧写的原理对于所有的板子都是一样的,只是烧写数据的来源和目标有区别,掌握原理以后就可以自己灵活修改,不用拿着从ftp烧写的脚本对着USB烧写的需求一筹莫展。:-)

你看到的是非授权版本!爬虫凶猛,请尊重知识产权!

转载请注明出处:http://conanwhf.github.io/2017/06/14/bootup-6-flasher/

访问原文「ARM板移植Linux系统启动(六)烧写系统到emmc」获取最佳阅读体验并参与讨论

BeagleBoneBlack的烧写

BeagleBoneBlack支持外部TF卡(emmc)烧写系统。它的流程是启动时长按某个button进入TF启动模式,然后修改init命令行参数让系统重新启动后自动运行烧写脚本。这个过程其实分几个步骤:

按住button调整启动模式。BeagleBoneBlack有两种顺序不同的启动模式:{SPI0,MMC0,USB0,UART0}和{MMC1,MMC0,UART0,USB0},按下时进入第二种模式。TF卡是外接在MMC1上,即意味着按下button时优先启动TF卡上的系统。注意这里的MMC0和MMC1是硬件意义上的,与进入系统后的设备结点mmc0,mmc1没有对应关系,可以不同。 BootROM在TF卡上寻找到uboot数据,进入uboot;然后uboot引导卡上的kernel,进入系统。 如果此时的init参数已经修改,则自动运行init指定的脚本,进行烧写系统的工作。 烧写完毕,系统自动断电,等待重新上电启动。

从这个过程我们可以推理出几件事:

因为引导系统的uboot也是来自于外部TF卡,这种烧写方法可以用在完全被破坏的无法启动的板子上,例如板载emmc被彻底擦除干净的设备。这就意味着你可以随意折腾你的板载系统,不用害怕,TF卡烧写是一种有效的救援措施 官方的烧写教程是让我们enable uEnv.txt中的一行代码cmdline=init=/opt/scripts/tools/eMMC/init-eMMC-flasher-v3.sh,这个flasher-v3.sh就是官方的烧写脚本。进入系统后手动运行效果也是一样的 从整个引导的过程来看,MMC0和MMC1的启动没有区别,所以实际上我们可以制作自己的TF卡系统而不是只局限于烧录,便于调试和使用(像RasspberryPi那样,换一张卡换个系统,甚至可以跑Windows),并且emmc是可读写的,修改的任何数据都会保留,不会重启消失 我们同样可以修改flasher-v3.sh,来完成自己的需求关于怎么玩BeagleBoneBlack,不是这篇文章的讨论重点,我只是为了弄清楚BeagleBoneBlack的烧写机制以为己用。TF卡烧写很好用,可惜我的板子没有TF卡。:( 烧写前的准备 编译kernel, uboot,获得zImage, MLO, u-boot.img等binary 准备一个根文件系统,通常Linux发行版会提供一个小型的文件系统,将Kernel镜像(一般放在/boot下),以及编译出来的驱动等等更新,打包并压缩。 编写合适的烧写脚本,等下会详细介绍。 确定你能进入console,并且在console里能access上面所提到的文件和脚本。 将准备好的文件拷贝进某个存储介质,例如USB,或者放在服务器端等待tftp获取。 烧写流程

flasher-v3.sh整个脚本很长,用的各种判断和变量也非常多,刚开始读难免眼花缭乱。我基于这个脚本,根据自己的需要,重新写了一份。文件系统烧写的原理都是一样:将存放源数据的设备挂载成文件夹A,将烧写的目标设备挂载成文件夹B,然后读取A中的数据解压,将文件系统写入B中。而对于bootloader的情况就比较复杂,他们的数据写入通常是不基于文件系统的,而写入的位置必须跟BootROM相对应,需要阅读厂商的文档。我做的项目不是开源,所以无法发布完整的烧写脚本,读者可以根据大致流程自行编写。

变量定义source="/dev/sda1" destination="/dev/mmcblk1" src="/tmp/usb/" dst="/tmp/dst/" spl_file="${src}/MLO" uboot_file="${src}/u-boot.img" rootfs_file="${src}/rootfs.tar.gz" boot_label="TEST" boot_fstype=ext3

这里定义几个全局变量方便使用,分别是数据源和目标设备的设备结点和挂载点,以及一些文件名的定义。读者可以根据需要自行修改,例如mmcblk1换成sdc1,或者从TF烧写而不是USB的时候将sda1换成mmcblk0p1等等。

烧写bootloader(uboot)

bootloader的烧写包括两个文件:MLO和u-boot.img,烧写是直接使用dd写入数据,参数来自TI官方release。

# 烧写之前先擦除整块emmc echo "Erasing: ${destination} any partion information" dd if=/dev/zero of=${destination} bs=1M count=20 sync # 烧写SPL和uboot spl_opt="count=1 seek=1 conv=notrunc bs=128k" uboot_opt="count=2 seek=1 conv=notrunc bs=384k" echo "dd if=${spl_file} of=${destination} ${spl_opt}" dd if=${spl_file} of=${destination} ${spl_opt} echo "dd if=${uboot_file} of=${destination} ${uboot_opt}" dd if=${uboot_file} of=${destination} ${uboot_opt} 对烧写的目标设备分区

过去,kernel的镜像文件的数据是不基于文件系统的,也就是并非以一个文件的形式存放在某个目录里,因为那时的uboot并没有文件系统的支持,只能从固定的块、页、扇区读取数据。后来特别是EFI被广泛运用后,将关键的文件系统相关数据写在一个单独的Fat32分区中成了一种普遍的方案,通常会将它们只读挂载在/boot下,系统数据和各种库文件是分开的,日常使用更加安全。而现在,uboot支持了更多的文件系统,也就使得我们可以将所有数据都放在一起,怎么设计这些分区,也就更加随意和灵活。TI所用的脚本中,就有了两种选择:fat+ext4或者整个emmc只有一个ext4分区。在这块板子上我选择了后面的方案,方便后期的开发和调试,烧写方案也比较简洁。烧写的工具使用的是sfdisk,请确保你的最小系统中包含这个工具。

# 参数变量设置 sfdisk_options="--force --Linux --in-order --unit M" sfdisk_boot_startmb=1 sfdisk_fstype="L" # 使用sfdisk分区 test_sfdisk=$(LC_ALL=C sfdisk --help | grep -m 1 -e "--in-order" || true) if [ "x${test_sfdisk}" = "x" ] ; then echo "sfdisk: [2.26.x or greater]" if [ "x${bootrom_gpt}" = "xenable" ] ; then sfdisk_options="--force --label gpt" else sfdisk_options="--force" fi sfdisk_boot_startmb="${sfdisk_boot_startmb}M" fi echo "sfdisk: [$(LC_ALL=C sfdisk --version)]" echo "sfdisk: [sfdisk ${sfdisk_options} ${destination}]" echo "sfdisk: [${sfdisk_boot_startmb},${sfdisk_boot_endmb},${sfdisk_fstype},*]" LC_ALL=C sfdisk ${sfdisk_options} "${destination}"


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3